home *** CD-ROM | disk | FTP | other *** search
- TITLE CRITERR.ASM
- SUBTTL TRAP CRITICAL ERRORS FROM W/IN C
-
- IFDEF ??version ;TASM
- %NOCONDS
- ELSE ;MASM
- .SFCOND ;DONT SHOW FALSE CONDITIONALS
- ENDIF
-
- ; MODULE CRITERR.ASM
- ; JANUARY 1991
- ; PETER HYMAN (609) 799-2638
- ; 148 TENNYSON DRIVE
- ; PLAINSBORO, NJ 08536
-
- ; MODIFIED 2/16/91 SEE NOTES AT END OF SOURCE FOR DESCRIPTION OF CHANGES
-
- ;;;;; TWO FUNCTIONS ;;;;;
-
- ; FUNCTION NAME: CRITERR( ONOFF )
- ; INPUTS 1 = TRAP CRITICAL ERRORS, 0 TURN OFF TRAP
- ; RETURNS 0 IF SUCCESSFUL, 1 IF ALREADY INSTALLED
-
- ; FUNCTION NAME: CLRCRITERR( )
- ; CLEAR CRITICAL ERROR VARIABLES
-
- ; ON CRITICAL ERRORS, INT 24H HANDLER WILL RETURN AN IGNORE CODE TO DOS
- ; IF VERSION < 3, OR A FAIL CODE FOR DOS >= 3
- ; IF VERSION >= 3, DOS FUNCTION 59H IS CALLED ALSO, AND EXTENDED ERROR
- ; INFO IS ALSO PUT INTO STRUCTURE
-
- ;;;;; USES SIMPLIFIED SEGMENT DIRECTIVES. ASSEMBLE WITH I8086S, M, C OR L
- ;;;;; DEFINED
-
- ;;;;; ASSEMBLE AS MASM/TASM /mx /dI8086[S|M|C|L] criterr;
- ;;;;; TURBO ASSEMBLER YIELDS SMALLER CODE WITH /Q OPTION
-
- IFDEF I8086S
- .MODEL SMALL
- p equ 4 ; p is offset into stack for args
- SCODE EQU 1
- ENDIF
- IFDEF I8086M
- .MODEL MEDIUM
- p equ 6
- LCODE equ 1
- ENDIF
- IFDEF I8086C
- .MODEL COMPACT
- p equ 4
- SCODE EQU 1
- LDATA EQU 1
- ENDIF
- IFDEF I8086L
- .MODEL LARGE
- p equ 6
- LCODE EQU 1
- LDATA EQU 1
- ENDIF
- IFNDEF I8086S
- IFNDEF I8086M
- IFNDEF I8086C
- IFNDEF I8086L
- %OUT NO MEMORY MODEL SPECIFIED
- END
- ENDIF
- ENDIF
- ENDIF
- ENDIF
-
- ;;;;; FORMAT FOR CRITICAL ERROR HEADER BLOCK ;;;;;
- ;;;;; CERTAIN CHAR VARIABLES EXPANDED TO INT FOR PROPER ALLIGNMENT ;;;;;
- CERR STRUC ; critical error structure
- ceflag db ? ; flag to indicate critical error 1 = yes
- cerrno db ? ; critical error number ; 2/16/91 changed to byte
- cerrtype dw ? ; critical error type/action/drive, AX
- drive db ? ; drive letter as a char
- read_wr db ? ; read or write error 1 = write
- disk_area db ? ; area of error, 0 = dos area, 1 = fat, 2 = dir, 3 = data
- resp_mask db ? ; allowable responses (moot)
- exterr db ? ; extended error number DOS >= 3 2/16/91 changed to byte
- eclass db ? ; error class
- action db ? ; action recommendations
- locus db ? ; locus
- nextdev dd ? ; next device pointer
- attr dw ? ; device attribute
- nxtfunc dw ? ; pointer to next strategy function
- intfunc dw ? ; pointer to interrupt function
- devname db 8 dup(?) ; device name
- dummy db ? ; terminating null
- CERR ENDS
-
- ; SEE DOS TECHNICAL REFERENCE FOR EXPLANATION OF CODES
-
-
- ;;;;; BEGIN DATA SEGMENT ;;;;; USING SIMPLIFIED SEGMENT DIRECTIVES
-
- .DATA ; begin data segment
- extrn __osmajor:byte ; operating system version
- _criterrtrap db 0 ; critical error flag 1=trapped, 0 = off
- ;;;;; GLOBAL ;;;;;
- public _cerr ; GLOBALS
- _cerr CERR <> ; CRITICAL ERROR STRUCTURE BLOCK
-
- .DATA? ; uninitialized data
- _oldint24vec label dword
- _oldint24off dw ? ; static vector to int 24 before trap
- _oldint24seg dw ? ;
-
-
- ; PROCEDURE CRITERR( ONOFF )
- ; SETS ALTERNATE CRITICAL ERROR HANDLER
- ; USAGE: criterr( 1 ) to set, criterr( 0 ) to turn off
-
- .CODE ; begin code segment
-
- savds dw 0 ; save proper data segment
-
- public _criterr
- ifdef SCODE
- _criterr proc
- else
- _criterr proc far
- endif
- push bp
- mov bp, sp
- push si
- push di
- mov ax, p[bp] ; see if a 0 or 1 was passed
- test ax, ax ; non zero?
- jne settrap ; 1, so set trap
- removetrap:
- cmp _criterrtrap, 1 ; see if installed
- jne done ; not installed, so return
- push ds
- lds dx, _oldint24vec ; restore original int 24 vector
- mov ax, 2524h
- int 21h ; dos set vector function
- pop ds
- mov _criterrtrap, 0 ; reset flag
- xor ax, ax ; set return code
- jmp done
- settrap:
- cmp _criterrtrap, 1 ; see if installed
- je done ; yes, so return (AX = 1)
- mov cs:savds, ds ; move current data segment to savds
- push es
- mov ax,03524h ; save old vector to int 24
- int 021h
- mov _oldint24off,bx
- mov _oldint24seg,es
- pop es
- push ds
- mov dx, offset cs:int_service ; load address of new routine
- mov ax,cs
- mov ds,ax
- mov ax,02524h ; set it
- int 021h
- pop ds
- mov _criterrtrap, 1 ; set flag
- xor ax, ax ;set return code
-
- done:
- push ax ; save AX
- ifdef LCODE
- call far ptr _clrcriterr ; reset values
- else
- call _clrcriterr
- endif
- pop ax
- pop di
- pop si
- pop bp
- ret ; return to caller, return code in AX
-
-
- ;;;;; NEW CRITICAL ERROR HANDLER ;;;;;
- ;;;;; SEE DOS TECHNICAL REFERENCE ;;;;;
-
- int_service: ;int 24 trap goes here
- push bp
- mov bp,sp ; set to critical stack frame
- push bx ; all used registers except AX must be
- push cx ; saved !!!!!
- push dx
- push si
- push di
- push ds
- push es
- pushf
- mov ds,cs:savds ; reset ds to program's ds
- mov bx, di ; save DI
- mov di, offset _cerr ; set di to point to structure cerr
- mov ceflag[di], 1 ; set ceflag 2/16/91
- mov cerrno[di], bl ; move to cerrno -- move byte only 2/16/91
- mov cerrtype[di],ax ; save error type/drive number
- test ax, 8000h ; char or block device
- mov bx, ax
- jnz response ; char device, so skip
- add bl, 'A' ; add letter A
- mov drive[di], bl ; move drive over
- and bh, 00000110b ; leave only bits 1 and 2
- shr bh,1 ; shift it over 1
- mov disk_area[di], bh ; save area of error
- mov bh, ah
- response: ; determine response possibilities
- and bh, 1 ; 2/16/91 this block moved from prev para.
- mov read_wr[di], bh ; move read write flag
- mov bh, ah
- and bh, 00111000b ; leave only bits 3-5
- shr bh,1
- shr bh,1
- shr bh,1 ; shift it over
- mov resp_mask[di],bh ; save response mask
- move_dev_header: ; move device header block
- push ds ; set up data registers
- pop es
- mov bx,[bp] ; load bp to get segment for device header
- mov ds,bx ; si contains offset of device header
- mov di,offset _cerr.nextdev ; copy device header block
- cld
- mov cx,9
- rep movsw ; move 18 bytes of device header block
- push es
- pop ds ; restore data registers
-
- ; now check for DOS version
- xor ax,ax ; return code ignore for dos < 3
- cmp __osmajor,3 ; dos >= 3?
- jl doneint ; no
- ; prepare to get extended error
- mov bx, 0
- mov ah, 59h ; get dos extended error
- int 21h ; call dos
- mov di, offset _cerr; set di to point to cerr structure
- mov exterr[di], al ; error code -- move byte only 2/16/91
- mov eclass[di], bh ; error class
- mov action[di], bl ; action
- mov locus[di], ch ; locus
- mov al, 3 ; return fail code
- doneint:
- popf
- pop es
- pop ds
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop bp ; restore stack frame
- iret ; return from interrupt
- _criterr endp
-
- ;;;;; FUNCTION TO CLEAR CRITICAL ERROR STATUS ;;;;;
-
- ;;;;; USAGE: clrcriterr()
-
- public _clrcriterr
- ifdef SCODE
- _clrcriterr proc ; function to clear critical error number
- else
- _clrcriterr proc far ; function to clear critical error number
- endif
-
- push bp
- mov bp,sp
- push di
- push ds
- pop es
- xor ax,ax ; zero entire structure
- mov di, offset _cerr
- mov cx, size _cerr ; get size of entire block
- rep stosb
- pop di
- pop bp
- ret
- _clrcriterr endp
-
- end
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ; PROGRAM MODIFICATIONS
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ; MODIFIED 2/16/91 TO INCLUDE THE FOLLOWING
- ; STRUCTURE MEMBER ceflag ADDED
- ; THIS WAS REQUIRED TO DETECT CRITICAL ERRORS, SINCE cerrno COULD HAVE
- ; A VALUE OF 0 WHICH WOULD INDICATE A WRITE PROTECT ERROR. ceflag WILL
- ; BE SET IT THERE WAS A CRITICAL ERROR
- ; CALLS TO EXTERNAL FUNCTION _dos_exterr REMOVED
- ; STUCTURE MEMBERS cerrno AND exterr CHANGED TO BYTE SIZE
- ; STRUCTURE MEMBER pad REMOVED BECAUSE ABOVE MADE IT UNNECESSARY
- ; THE CODE WHICH SET THE read_wr STRUCTURE MEMBER WAS MOVED TO JUST
- ; BELOW THE response: LABEL SINCE IT WAS NOT CORRECTLY LOCATED PREVIOUSLY
- ; AND WOULD NEVER BE SET FOR NON-DISK ERRORS
- ; TESTS TO SEE IF HANDLER WAS ALREADY INSTALLED WERE CHANGED. IT WAS
- ; POSSIBLE TO INSTALL THE HANDLER MULTIPLE TIMES THEREBY REMOVING THE
- ; ABILITY TO UNINSTALL IT. CODE AFTER removetrap: AND settrap: WAS MODIFIED
- ; TO COMPARE FLAG.
- ; cerr STRUCTURE WILL BE RESET WHENEVER THE CRITERR FUNCTION IS CALLED. IF
- ; IS INSTALLED, REMOVED.
-